using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
namespace Circus.CodeEditor {

    [ToolboxItem(false)]
    [DesignerCategory("Code")]
    public class SpeedButton : Control {
        private const int DefaultButtonSize = 18;
        private Painter painter;
        private ImageList images;
        private bool hot;
        private int imageIndex = -1;
        private EditBorderStyle borderStyle = EditBorderStyle.None;
        private bool isChecked = false;
        private bool allowCheck = false;

        [Description("Occurs when the value of the Checked property changes.")]
        public event EventHandler CheckedChanged;
        protected bool Hot {
            get {
                return this.hot;
            }
            set {
                if (this.hot != value) {
                    this.hot = value;
                    base.Invalidate();
                }
            }
        }

        protected bool Pressed {
            get {
                return this.allowCheck ? this.isChecked : (this.hot && Control.MouseButtons == MouseButtons.Left);
            }
        }

        public ImageList ImageList {
            get {
                return this.images;
            }
            set {
                if (this.images != value) {
                    this.images = value;
                    this.OnImagesChanged();
                }
            }
        }

        public int ImageIndex {
            get {
                return this.imageIndex;
            }
            set {
                if (this.imageIndex != value) {
                    this.imageIndex = value;
                    this.OnImageIndexChanged();
                }
            }
        }

        public EditBorderStyle BorderStyle {
            get {
                return this.borderStyle;
            }
            set {
                if (this.borderStyle != value) {
                    this.borderStyle = value;
                    this.OnBorderStyleChanged();
                }
            }
        }

        public bool Checked {
            get {
                return this.isChecked;
            }
            set {
                if (this.isChecked != value) {
                    this.isChecked = value;
                    this.OnCheckedChanged(new EventArgs());
                    base.Invalidate();
                }
            }
        }

        public bool AllowCheck {
            get {
                return this.allowCheck;
            }
            set {
                if (this.allowCheck != value) {
                    this.allowCheck = value;
                    this.OnAllowCheckChanged();
                }
            }
        }

        private Color GetBkColor() {
            Color result;
            switch (this.borderStyle) {
                case EditBorderStyle.None:
                case EditBorderStyle.FixedSingle:
                    if (this.Pressed) {
                        result = Consts.DefaultPressedBackColor;
                        return result;
                    }
                    if (this.Hot) {
                        result = Consts.DefaultHotTrackBackColor;
                        return result;
                    }
                    break;
            }
            result = this.BackColor;
            return result;
        }

        protected override void OnPaint(PaintEventArgs e) {
            Rectangle rectangle = base.ClientRectangle;
            this.painter.BeginPaint(e.Graphics);
            try {
                switch (this.borderStyle) {
                    case EditBorderStyle.None:
                        if (this.hot) {
                            this.painter.BackColor = Consts.DefaultHotTrackColor;
                            this.painter.DrawRectangle(new Rectangle(rectangle.Left, rectangle.Top, rectangle.Width - 1, rectangle.Height - 1));
                            rectangle.Inflate(-1, -1);
                        }
                        break;
                    case EditBorderStyle.Fixed3D:
                    case EditBorderStyle.System:
                        if (this.borderStyle == EditBorderStyle.System && XPThemes.CurrentTheme != XPThemeName.None) {
                            XPThemes.DrawPushButton(this.painter, rectangle, this.Pressed, this.Hot);
                        } else {
                            Rectangle rectangle2 = rectangle;
                            this.painter.DrawEdge(ref rectangle, this.Pressed ? Border3DStyle.Sunken : Border3DStyle.Raised, Border3DSide.All);
                            rectangle = rectangle2;
                            rectangle.Inflate(-2, -2);
                        }
                        break;
                    case EditBorderStyle.FixedSingle:
                        this.painter.BackColor = Consts.DefaultWindowFrameColor;
                        this.painter.DrawRectangle(new Rectangle(rectangle.Left, rectangle.Top, rectangle.Width - 1, rectangle.Height - 1));
                        rectangle.Inflate(-1, -1);
                        break;
                }
                this.painter.BackColor = this.GetBkColor();
                if (this.borderStyle != EditBorderStyle.System) {
                    this.painter.FillRectangle(rectangle);
                }
                if (this.images != null) {
                    Rectangle rect = new Rectangle(Point.Empty, this.images.ImageSize);
                    int x = base.ClientRectangle.Left + (rectangle.Width - rect.Width) / 2;
                    int y = base.ClientRectangle.Top + (rectangle.Height - rect.Height) / 2;
                    rect.Offset(x, y);
                    rect.Intersect(rectangle);
                    this.painter.DrawImage(this.images, this.imageIndex, rect);
                }
            } finally {
                this.painter.EndPaint();
            }
        }

        protected override void OnMouseDown(MouseEventArgs e) {
            base.OnMouseDown(e);
            if (this.allowCheck && e.Button == MouseButtons.Left) {
                this.Checked = !this.Checked;
            }
            base.Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs e) {
            base.OnMouseUp(e);
            base.Invalidate();
        }
        protected override void OnMouseMove(MouseEventArgs e) {
            base.OnMouseMove(e);
            this.Hot = true;
        }
        protected override void OnMouseLeave(EventArgs e) {
            base.OnMouseLeave(e);
            this.Hot = false;
        }
        protected virtual void OnImagesChanged() {
            base.Invalidate();
        }
        protected virtual void OnImageIndexChanged() {
            base.Invalidate();
        }
        protected virtual void OnBorderStyleChanged() {
            base.Invalidate();
        }
        protected virtual void OnAllowCheckChanged() {
        }
     
        public SpeedButton() {
            base.SetStyle(ControlStyles.DoubleBuffer, true);
            base.Width = 18;
            base.Height = 18;
            this.painter = new Painter();
            base.SetStyle(ControlStyles.UserPaint | ControlStyles.StandardClick | ControlStyles.Selectable | ControlStyles.UserMouse | ControlStyles.StandardDoubleClick | ControlStyles.AllPaintingInWmPaint, true);
            base.SetStyle(ControlStyles.Opaque, false);
            this.Cursor = Cursors.Default;
            this.BackColor = SystemColors.Control;
        }
        public virtual void OnCheckedChanged(EventArgs args) {
            if (this.CheckedChanged != null) {
                this.CheckedChanged(this, args);
            }
        }
    }

}
